/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ftpcombiner.gui.applicationframe;

import ftpcombiner.ApplicationController;
import ftpcombiner.gui.GUILoader;
import java.awt.BorderLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.border.EmptyBorder;

/**
 *
 * @author Ben
 */
public class StatusBar extends JPanel implements GUILoader {

    private JProgressBar progressBar;
    private JLabel statusLabel;
    private TimeoutThread timeoutThread;
    private String status = "Ready";
    private boolean persist = false;

    public StatusBar() {
        init();
    }

    private void init() {
        initializeComponents();
        otherInit();
        setLayouts();
        addComponents();
        addComponentListeners();
    }

    @Override
    public void initializeComponents() {
        progressBar = new JProgressBar(0, 100);
        statusLabel = new JLabel("Ready");
    }

    @Override
    public void setLayouts() {

        setLayout(new BorderLayout(5, 0));
    }

    @Override
    public void addComponents() {
        add(progressBar, BorderLayout.EAST);
        add(statusLabel, BorderLayout.WEST);
    }

    @Override
    public void addComponentListeners() {
    }

    @Override
    public void otherInit() {
        setBorder(new EmptyBorder(2, 5, 2, 5));
        progressBar.setVisible(false);
        timeoutThread = new TimeoutThread();
        ApplicationController.getSplashScreen().incrementProgress();
    }

    public JProgressBar getProgressBar() {
        return progressBar;
    }

    public JLabel getStatusLabel() {
        return statusLabel;
    }

    /**
     * Sets the status string in the status bar at the bottom of the
     * {@link ApplicationFrame}. This method is usually called instead using
     * {@link ApplicationController#setAppStatus(java.lang.String)} for
     * convenience. Note: When persist is used, make sure to manually turn off
     * persist when the status is no longer relevant.
     *
     * @param status The string to set that should be used in the status bar
     * @param persist Whether the status should remain in place until it is
     * overwritten or timeout after 6s
     * @see ApplicationController#setAppStatus(java.lang.String)
     */
    public void setStatus(String status, boolean persist) {
        this.status = status;
        this.persist = persist;
        synchronized (timeoutThread.lock) {
            timeoutThread.timeout = TimeoutThread.MAXTIMEOUT;
        }
        try {
            timeoutThread.start();
        } catch (IllegalThreadStateException ex) {
            synchronized (timeoutThread) {
                timeoutThread.notify();
            }
        }
    }

    private class TimeoutThread extends Thread {

        protected static final int MAXTIMEOUT = 6000;
        protected int timeout = MAXTIMEOUT;
        protected final Object lock = new Object();

        public TimeoutThread() {
            super("TimeoutThread");
        }

        @Override
        public void run() {
            while (true) {
                statusLabel.setText(status);
                synchronized (lock) {
                    timeout = MAXTIMEOUT;
                }
                while (timeout > 0) {
                    try {
                        Thread.sleep(100);
                        synchronized (lock) {
                            timeout -= 100;
                        }
                        if (!statusLabel.getText().equals(status)) {
                            statusLabel.setText(status);
                        }
                    } catch (InterruptedException ex) {
                    }

                }
                status = "Ready";
                if (!persist) {
                    statusLabel.setText(status);
                }
                synchronized (this) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }
}
